<?php

/**
 * 云汇算
 */

declare(strict_types=1);

namespace app\api\controller;

use app\api\controller\Signsha;
use app\common\model\WithdrawalChannel;
use app\common\model\WithdrawalOrder;
use think\Controller;
use think\Db;

class Cloudcomputing extends Controller
{
    /**************************** 单笔提现申请 ****************************/
    // 生产地址
    private static $single_withdrawal_url = 'https://service-pay.huiis.cn/api/pay/apply';

    /**************************** 单笔提现结果查询 ****************************/
    // 生产地址
    private static $single_withdrawal_result_query_url = 'https://service-pay.huiis.cn/api/pay/query';

    /**************************** 从业者数据提交 ****************************/
    // 生产地址
    private static $practitioner_create_url = 'https://service-pay.huiis.cn/api/personal/create';

    /**************************** 发起签约确认 ****************************/
    // 生产地址
    private static $practitioner_sign_url = 'https://service-pay.huiis.cn/api/personal/sign';

    /**************************** 签约状态查询 ****************************/
    // 生产地址
    private static $practitioner_sign_query_url = 'https://service-pay.huiis.cn/api/personal/signed/result';

    /**************************** 查询平台余额 ****************************/
    // 生产地址
    private static $balanceQuery = 'https://service-pay.huiis.cn/api/account/balance';

    /**
     * 单笔提现申请
     */
    public static function singleWithdrawal($order_number, $cloudcomputingData)
    {
        if (!empty($order_number)) {
            $order_info = WithdrawalOrder::where(['order_number' => $order_number])->find()->toArray();
            if (!empty($order_info)) {
                $data = [
                    "apiCode" => "1000",
                    "enterpriseNo" => $cloudcomputingData["enterprise_code"],
                    "channelNo" => $cloudcomputingData["channel_code"],
                    "timestamp" => self::getMillisecond(),
                    "taskNo" => $cloudcomputingData["task_code"],
                    "entOrderNo" => $order_info["order_number"],
                    "payeeName" => $order_info["name"],
                    "payeeIdCard" => $order_info["idcards"],
                    "payeePhone" => $order_info["phone"],
                    "payeeAccount" => $order_info["bank_card_number"],
                    "paymentModel" => "100",
                    "amount" => $order_info["arrival_amount"] * 100,
                    "callbackUrl" => config("app_url") . "/api/Cloudcomputing/notifyUrl",
                    "remark" => ''
                ];
                $saveData = [
                    "order_number" => $order_info["order_number"],
                    "amount" => $order_info["arrival_amount"],
                    "service_fee" => 0,
                    "real_amount" => 0,
                    "create_time" => date("Y-m-d H:i:s"),
                    "remarks" => $data["remark"]
                ];
                $body = Signsha::getEncrypt(json_encode($data), $cloudcomputingData["public_key"]);
                $sendData = [
                    "enterpriseNo" => $cloudcomputingData["enterprise_code"],
                    "channelNo" => $cloudcomputingData["channel_code"],
                    "body" => $body
                ];
                self::savePayOrder($saveData);
                $res = self::jsonCurl(self::$single_withdrawal_url, $sendData);
                $saveData["pay_status"] = $res["code"];
                $saveData["port_info"] = $res["msg"];
                if ($res["code"] == '000000') {
                    $saveData["pay_time"] = $res["data"]["applyTime"];
                    $saveData["serial_order"] = $res["data"]["pfOrderNo"];
                    $return = ["code" => 200, "msg" => $res["msg"]];
                } else {
                    $return = ["code" => 400, "msg" => $res["msg"]];
                }
                self::savePayOrder($saveData);
            } else {
                $return = ["code" => 500, "msg" => "代付订单不存在！"];
            }
        } else {
            $return = ["code" => 500, "msg" => "参数错误！"];
        }
        return $return;
    }

    /**
     * 单笔提现结果查询
     */
    public function singleWithdrawalResultQuery()
    {
        $params = input();
        $entOrderNo = isset($params["order_number"]) ? $params["order_number"] : 'cs0000111100001';
        if (!empty($entOrderNo)) {
            $withdrawal_channel = WithdrawalChannel::where('status', 1)->find();
            if (!empty($withdrawal_channel)) {
                $data = [
                    "enterpriseNo" => $withdrawal_channel->enterprise_code,
                    "channelNo" => $withdrawal_channel->channel_code
                ];
                $body = [
                    "apiCode" => '1001',
                    "enterpriseNo" => $withdrawal_channel->enterprise_code,
                    "channelNo" => $withdrawal_channel->channel_code,
                    "timestamp" => self::getMillisecond(),
                    "entOrderNo" => $entOrderNo
                ];
                $apiData = [
                    "api_code" => $body["apiCode"],
                    "ent_order_number" => $entOrderNo,
                    "apply_time" => date("Y-m-d H:i:s")
                ];
                $body = Signsha::getEncrypt(json_encode($body), $withdrawal_channel->public_key);
                $data["body"] = $body;
                $res = self::jsonCurl(self::$single_withdrawal_result_query_url, $data);
                $apiData["code"] = $res["code"];
                $apiData["msg"] = $res["msg"];
                $apiData["return_content"] = json_encode($res);
                self::apiPortLogs($apiData);
                if ($res["code"] == '000000') {
                    $pay_order_data = [
                        "service_fee" => $res["data"]["fee"] / 100,
                        "real_amount" => ($res["data"]["amount"] + $res["data"]["fee"]) / 100,
                        "pay_status" => $res["code"],
                        "port_info" => $res["msg"],
                        "deal_status" => $res["data"]["status"],
                        "serial_order" => $res["data"]["refOrderNo"]
                    ];
                    if (isset($res["data"]["finishTime"])) {
                        $pay_order_data["deal_time"] = $res["data"]["finishTime"];
                    }
                    Db::name("cloud_transfer_order")->where(["order_number" => $res["data"]["entOrderNo"]])->update($pay_order_data);

                    switch ($res["data"]["status"]) {
                            # 交易中
                        case '100':
                            $code = 20;
                            $msg = '交易中';
                            break;
                            # 交易中
                        case '200':
                            $code = 20;
                            $msg = '交易中';
                            break;
                            # 交易成功
                        case '300':
                            $code = 30;
                            $msg = '交易成功';
                            break;
                            # 交易失败
                        case '400':
                            $code = 40;
                            $msg = '交易失败';
                            break;
                        default:
                            $code = 50;
                            $msg = '交易未知';
                    }
                    $return = ["code" => 200, "msg" => '查询成功', 'data' => ['code' => $code, 'msg' => $msg]];
                } else {
                    $return = ["code" => 400, "msg" => $res["msg"]];
                }
            } else {
                $return = ["code" => 500, "msg" => "提现通道未配置！"];
            }
        } else {
            $return = ["code" => 500, "msg" => "参数错误！"];
        }
        return json($return);
    }

    /**
     * 回调通知
     */
    public function notifyUrl()
    {
        $params = input();
        if (!empty($params)) {
            file_put_contents('./Withdrawal.log', json_encode($params), FILE_APPEND);
            $pay_order_data = [
                "service_fee" => $params["body"]["fee"] / 100,
                "real_amount" => ($params["body"]["amount"]) / 100,
                "deal_time" => $params["body"]["finishTime"],
                "deal_status" => $params["body"]["status"],
                "serial_order" => $params["body"]["refOrderNo"]
            ];
            Db::name("cloud_transfer_order")->where(["order_number" => $params["body"]["entOrderNo"]])->update($pay_order_data);
            $dataArray = [
                'payment_time' => time(),
                'port_content' => '成功'
            ];
            if (isset($params["body"]["status"])) {
                if ($params["body"]["status"] == "300") {
                    $dataArray['payment_status'] = 2;                                           # 交易成功
                    $dataArray['port_service_fee'] = $params["body"]["fee"] / 100;              # 系统代付金额
                    // 余额提现 支出日志记录
                    \app\api\controller\balance\Withdraw::instance()->changs_balance_cords($params["body"]["entOrderNo"]);
                } else if ($params["body"]["status"] == "400" || $params["body"]["status"] == "500") {
                    $dataArray['payment_status'] = 3;
                }
                # 更新订单状态
                WithdrawalOrder::where(['order_number' => $params["body"]["entOrderNo"]])->update($dataArray);
            }
        }
        echo json_encode(["handled" => "SUCCESS"]);
    }

    /**
     * 从业者数据提交
     */
    public static function practitionerDataSubmission($data = null, $cloudcomputingData)
    {
        if (!empty($data)) {
            $sale_id = isset($data["sale_id"]) ? $data["sale_id"] : 0;
            $info = Db::name("user")->alias("a")->join("user_card b", "b.sale_id = a.id", "LEFT")->where(['a.id' => $sale_id])->find();
            $params = [
                "enterpriseNo" => $cloudcomputingData["enterprise_code"],
                "channelNo" => $cloudcomputingData["channel_code"]
            ];
            if (!empty($info)) {
                $bankcard = Db::name("bank_card")->where('status', '=', 1)->where('sale_id', '=', $sale_id)->find();
                if (!empty($bankcard)) {
                    if (self::getPractitionerInfo($sale_id) <= 0) {
                        $body = [
                            "apiCode" => "3000",
                            "enterpriseNo" => $cloudcomputingData["enterprise_code"],
                            "channelNo" => $cloudcomputingData["channel_code"],
                            "timestamp" => self::getMillisecond(),
                            "name" => $bankcard["name"],
                            "idCard" => $bankcard["idcards"],
                            "phone" => $bankcard["phone"],
                            "bankCard" => $bankcard["bank_card_number"],
                            "htSource" => 90
                        ];
                        $apiData = [
                            "api_code" => $body["apiCode"],
                            "ent_order_number" => $body["idCard"],
                            "apply_time" => date("Y-m-d H:i:s")
                        ];
                        $saveData = [
                            "main_type" => 2,
                            "sale_id" => $sale_id,
                            "name" => $body["name"],
                            "id_card" => $body["idCard"],
                            "phone" => $body["phone"],
                            "bank_card" => $body["bankCard"],
                            "ht_source" => $body["htSource"]
                        ];
                        $body = Signsha::getEncrypt(json_encode($body), $cloudcomputingData["public_key"]);
                        $params["body"] = $body;
                        $fileData = [
                            "frontCertImg" => self::imgToBase64(config("app_url") . $info["card_front"]), //身份证正面照
                            "backCertImg" => self::imgToBase64(config("app_url") . $info["card_back"]), //身份证反面照
                        ];
                        $saveData["front_cert_img"] = $info["card_front"];
                        $saveData["back_cert_img"] = $info["card_back"];
                        $saveData["create_time"] = date("Y-m-d H:i:s");
                        $params["fileData"] = $fileData;
                        self::savePractitioner($saveData);
                        $res = self::jsonCurl(self::$practitioner_create_url, $params);
                        $apiData["code"] = $res["code"];
                        $apiData["msg"] = $res["msg"];
                        $apiData["return_content"] = json_encode($res);
                        self::apiPortLogs($apiData);
                    }
                }
            }
        }
    }

    /**
     * 从业者发起签约
     */
    public function practitionerSign($idcards = '')
    {

        if (!empty($idcards)) {
            $withdrawal_channel = WithdrawalChannel::where('status', 1)->find();
            if (!empty($withdrawal_channel)) {
                $params = [
                    "enterpriseNo" => $withdrawal_channel->enterprise_code,
                    "channelNo" => $withdrawal_channel->channel_code
                ];
                $body = [
                    "apiCode" => "3004",
                    "enterpriseNo" => $withdrawal_channel->enterprise_code,
                    "channelNo" => $withdrawal_channel->channel_code,
                    "timestamp" => self::getMillisecond(),
                    "idCard" => $idcards
                ];
                $apiData = [
                    "api_code" => $body["apiCode"],
                    "ent_order_number" => $body["idCard"],
                    "apply_time" => date("Y-m-d H:i:s")
                ];
                $body = Signsha::getEncrypt(json_encode($body), $withdrawal_channel->public_key);
                $params["body"] = $body;
                $res = self::jsonCurl(self::$practitioner_sign_url, $params);
                $apiData["code"] = $res["code"];
                $apiData["msg"] = $res["msg"];
                $apiData["return_content"] = json_encode($res);
                self::apiPortLogs($apiData);
            }
        }
    }

    /**
     * 从业者签约状态查询
     */
    public static function practitionerSignResult($idcards = '150223199003181214')
    {
        if (!empty($idcards)) {
            $withdrawal_channel = WithdrawalChannel::where('status', 1)->find();
            if (!empty($withdrawal_channel)) {
                $params = [
                    "enterpriseNo" => $withdrawal_channel->enterprise_code,
                    "channelNo" => $withdrawal_channel->channel_code
                ];
                $body = [
                    "apiCode" => "3003",
                    "enterpriseNo" => $withdrawal_channel->enterprise_code,
                    "channelNo" => $withdrawal_channel->channel_code,
                    "timestamp" => self::getMillisecond(),
                    "idCard" => $idcards
                ];
                $apiData = [
                    "api_code" => $body["apiCode"],
                    "ent_order_number" => $body["idCard"],
                    "apply_time" => date("Y-m-d H:i:s")
                ];
                $body = Signsha::getEncrypt(json_encode($body), $withdrawal_channel->public_key);
                $params["body"] = $body;
                $res = self::jsonCurl(self::$practitioner_sign_query_url, $params);
                $apiData["code"] = $res["code"];
                $apiData["msg"] = $res["msg"];
                $apiData["return_content"] = json_encode($res);
                self::apiPortLogs($apiData);
                if ($res["code"] == "000000") {
                    if ($res["data"]["result"] == "200") {
                        Db::name("cloud_transfer_practitioner")->where(["id_card" => $idcards])->update(["is_sign" => 2, "sign_time" => date('Y-m-d H:i:s')]);
                    }
                }
            }
        }
    }

    /**
     * 手动从业者签约状态查询
     */
    public function practitionerSignResultSubmit()
    {
        $params = input();
        $page = isset($params["page"]) ? $params["page"] : 1;
        $limit = 500;
        $offset = ($page - 1) * $limit;
        $practitioner = Db::name("cloud_transfer_practitioner")->where(["is_sign" => 1])->order("create_time desc")->limit($offset, $limit)->select();
        for ($i = 0; $i < count($practitioner); $i++) {
            self::practitionerSignResult($practitioner[$i]["id_card"]);
        }
    }

    /**
     * 平台余额查询
     */
    public static function balanceQuery()
    {
        $balance = 0;
        $withdrawal_channel = WithdrawalChannel::where('status', 1)->find();
        if (!empty($withdrawal_channel)) {
            $params = [
                "enterpriseNo" => $withdrawal_channel->enterprise_code,
                "channelNo" => $withdrawal_channel->channel_code
            ];
            $body = [
                "apiCode" => "2001",
                "enterpriseNo" => $withdrawal_channel->enterprise_code,
                "channelNo" => $withdrawal_channel->channel_code,
                "timestamp" => self::getMillisecond()
            ];
            $apiData = [
                "api_code" => $body["apiCode"],
                "ent_order_number" => 'YECX',
                "apply_time" => date("Y-m-d H:i:s")
            ];
            $body = Signsha::getEncrypt(json_encode($body), $withdrawal_channel->public_key);
            $params["body"] = $body;
            $res = self::jsonCurl(self::$balanceQuery, $params);
            $apiData["code"] = $res["code"];
            $apiData["msg"] = $res["msg"];
            $apiData["return_content"] = json_encode($res);
            self::apiPortLogs($apiData);
            if ($res["code"] == "000000") {
                $balance = $res["data"]["usableAmt"];
                $data = [
                    "enterpriseNo" => $params["enterpriseNo"],
                    "channelNo" => $params["channelNo"],
                    "usableAmt" => $res["data"]["usableAmt"],
                    "freezeAmt" => $res["data"]["freezeAmt"],
                    "status" => 1,
                    "create_time" => date('Y-m-d H:i:s')
                ];
                Db::name("cloud_transfer_balance")->insert($data);
            }
        }
        return (int)$balance;
    }

    public function getBalanceQuery()
    {
        $balance = self::balanceQuery();
        echo $balance;
        // $phone = "18748149147";
        // $money = "50.03";
        // sendSms(63, $money, $phone);
    }

    /**
     * curl 请求方式错误
     * @param string $url
     * @param array $data
     * @return false|mixed
     */
    public static function jsonCurl($url = "", $data = [])
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json", "charset: utf-8"));
        $response = curl_exec($ch);
        if ($response === false) {
            echo 'curl请求错误:' . curl_error($ch);
        }
        curl_close($ch);
        return json_decode($response, true);
    }

    /**
     * 获取毫秒
     */
    public static function getMillisecond()
    {
        list($t1, $t2) = explode(' ', microtime());
        return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
    }

    /**
     * 获取图片的Base64编码(不支持url)
     * @date 2017-02-20 19:41:22
     *
     * @param $img_file 传入本地图片地址
     *
     * @return string
     */
    public static function imgToBase64($img_file)
    {
        $img_base64 = '';
        if (file_exists($img_file)) {
            $app_img_file = $img_file; // 图片路径
            $img_info = getimagesize($app_img_file); // 取得图片的大小，类型等
            $fp = fopen($app_img_file, "r"); // 图片是否可读权限
            if ($fp) {
                $filesize = filesize($app_img_file);
                $content = fread($fp, $filesize);
                $file_content = chunk_split(base64_encode($content)); // base64编码
                switch ($img_info[2]) {           //判读图片类型
                    case 1:
                        $img_type = "gif";
                        break;
                    case 2:
                        $img_type = "jpg";
                        break;
                    case 3:
                        $img_type = "png";
                        break;
                }
                $img_base64 = 'data:image/' . $img_type . ';base64,' . $file_content; //合成图片的base64编码

            }
            fclose($fp);
        }
        return $img_base64; //返回图片的base64
    }

    /**
     * 存储接口信息
     */
    public static function apiPortLogs($data)
    {
        if (!empty($data)) {
            Db::name("cloud_transfer_port_logs")->insert($data);
        }
    }

    /**
     * 存储从业者信息
     */
    public static function savePractitioner($data)
    {
        if (!empty($data)) {
            $info = Db::name("cloud_transfer_practitioner")->where(['sale_id' => $data["sale_id"]])->find();
            if (!empty($info)) {
                Db::name("cloud_transfer_practitioner")->where('sale_id', '=', $data["sale_id"])->update($data);
            } else {
                Db::name("cloud_transfer_practitioner")->insert($data);
            }
        }
    }

    /**
     * 存储提现信息
     */
    public static function savePayOrder($data)
    {
        if (!empty($data)) {
            $info = Db::name("cloud_transfer_order")->where(['order_number' => $data["order_number"]])->find();
            if (!empty($info)) {
                Db::name("cloud_transfer_order")->where('order_number', '=', $data["order_number"])->update($data);
            } else {
                Db::name("cloud_transfer_order")->insert($data);
            }
        }
    }

    /**
     * 获取从业者信息
     */
    public static function getPractitionerInfo($sale_id)
    {
        $nums = Db::name("cloud_transfer_practitioner")->where('sale_id', '=', $sale_id)->count();
        return $nums;
    }
}
